home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / b / b.lha / B / src / bed / tabl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-11-24  |  16.0 KB  |  520 lines

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2.  
  3. /* 
  4.  * $Header: tabl.c,v 2.4 85/08/22 16:08:42 timo Exp $
  5.  */
  6.  
  7. /*
  8.  * B editor -- Grammar table.
  9.  */
  10.  
  11. #include "b.h"
  12. #include "node.h"
  13. #include "gram.h"
  14. #include "tabl.h"
  15.  
  16.  
  17. /*
  18.  * ***** DISCLAIMER *****
  19.  *
  20.  * This file is a mess.  There should really be a separate program (like Yacc)
  21.  * to compile a grammar into tables.  But for the time being . . .
  22.  */
  23.  
  24.  
  25. /*
  26.  * Values returned by function symbol(n).
  27.  * They are used directly as index in the grammar table.
  28.  * The NAMES of the #defined constants are of no importance outside this file.
  29.  */
  30.  
  31. #define Put    1
  32. #define Insert    2
  33. #define Remove    3
  34. #define Choose    4
  35. #define Draw    5
  36. #define Set_random    6
  37. #define Delete    7
  38. #define Check    8
  39. #define Share    9
  40.  
  41. #define Write    10
  42. #define Read    11
  43. #define Read_raw    12
  44.  
  45. #define If    13
  46. #define While    14
  47. #define For    15
  48.  
  49. #define Select    16
  50.  
  51. #define Quit    18
  52. #define Return    19
  53. #define Report    20
  54. #define Succeed    21
  55. #define Fail    22
  56.  
  57. #define How_to    23
  58. #define Yield    24
  59. #define Test    25
  60. #define Suite    26
  61. #define Refinement    27
  62.  
  63. #define Compound    28
  64. #define Collateral    29
  65. #define Tag    30
  66. #define Number    31
  67. #define Selection    32
  68. #define Behead    33
  69. #define Curtail    34
  70.  
  71. #define And    35
  72. #define Or    36
  73. #define Not    37
  74. #define Some_in    38
  75. #define Each_in    39
  76. #define No_in    40
  77. #define Some_parsing    41
  78. #define Each_parsing    42
  79. #define No_parsing    43
  80.  
  81. #define Comment    44
  82. #define Keyword    45
  83.  
  84. #define L_t_dis    46
  85. #define List_body    47
  86. #define Tab_body    48
  87. #define Tab_entry    49
  88.  
  89. #define E_number    50
  90. #define Com_target    51
  91. #define Col_target    52
  92. #define Sel_expr    53
  93. #define Text1    54
  94. #define Text2    55
  95. #define Grouped    56
  96. #define Blocked    57
  97. #define Operators    58
  98.  
  99. #define Else_kw    59
  100. #define Kw_plus    60
  101. #define E_plus    61
  102. #define Conversion    62
  103. #define T1    63
  104. #define T1_plus    64
  105. #define T2    65
  106. #define T2_plus    66
  107. #define Cmt_cmd    67
  108.  
  109. #define F_kw_plus    69
  110. #define F_e_plus    70
  111. #define Plus_sign    71
  112. #define Minus_sign    72
  113.  
  114. #define Long_comp    73
  115. #define Short_comp    74
  116. #define Cmt_comp    75
  117.  
  118. #define Long_unit    76
  119. #define Short_unit    77
  120. #define Cmt_head    78
  121.  
  122. #define Ref_join    79
  123.  
  124. #define And_kw    80
  125. #define Or_kw    81
  126.  
  127. #define E_part 82
  128.  
  129. #define Unit_edit    83
  130. #define Target_edit    84
  131. #define Imm_cmd    85
  132. #define Raw    86
  133. #define Raw_input    87
  134. #define Edit_unit    88
  135. #define Edit_target    89
  136. #define Colon    90
  137. #define Equals    91
  138. #define Test_suite    92
  139. #define Expression    93
  140.  
  141. /*
  142.  * The last three, `Suggestion', `Optional' and `Hole',
  143.  * with values 97, 98 and 99, are defined in "gram.h".
  144.  */
  145.  
  146.  
  147. /*
  148.  * Symbol values used for lexical elements.
  149.  * Cross-reference: "lexi.c", table `chclass'.
  150.  */
  151.  
  152. #define LEXICAL 100
  153.  
  154. #define IDENT (LEXICAL+0)
  155. #define KEYWORD (LEXICAL+1)
  156. #define NUMBER (LEXICAL+2)
  157. #define COMMENT (LEXICAL+3)
  158. #define TEXT1 (LEXICAL+4)
  159. #define TEXT2 (LEXICAL+5)
  160. #define OPERATORS (LEXICAL+6)
  161. #define RAWINPUT (LEXICAL+7)
  162. #define SUGGESTION (LEXICAL+8)
  163.  
  164.  
  165. /*
  166.  * Classes used in table initialization.
  167.  */
  168.  
  169. Hidden classelem Asugg_body[] = {SUGGESTION, 0};
  170.     Hidden struct classinfo sugg_body[] = {Asugg_body};
  171.  
  172. #define TARGET Tag, Com_target, Selection, Behead, Curtail
  173. #define PRIMARY \
  174.     Sel_expr, Tag, E_number, Number, Compound, L_t_dis, Text1, Text2
  175. #define EXPR Blocked, Grouped, Operators, PRIMARY
  176.  
  177. Hidden classelem Atag_body[] = {IDENT, 0};
  178.     Hidden struct classinfo tag_body[] = {Atag_body};
  179. Hidden classelem Anum_body[] = {NUMBER, 0};
  180.     Hidden struct classinfo num_body[] = {Anum_body};
  181. Hidden classelem Acom_body[] = {COMMENT, 0};
  182.     Hidden struct classinfo com_body[] = {Acom_body};
  183. Hidden classelem Akw_body[] = {KEYWORD, 0};
  184.     Hidden struct classinfo kw_body[] = {Akw_body};
  185. Hidden classelem At1_body[] = {TEXT1, 0};
  186.     Hidden struct classinfo t1_body[] = {At1_body};
  187. Hidden classelem At2_body[] = {TEXT2, 0};
  188.     Hidden struct classinfo t2_body[] = {At2_body};
  189. Hidden classelem Aops_body[] = {OPERATORS, 0};
  190.     Hidden struct classinfo ops_body[] = {Aops_body};
  191. Hidden classelem Araw_body[] = {RAWINPUT, 0};
  192.     Hidden struct classinfo raw_body[] = {Araw_body};
  193. Hidden classelem Araw_input[] = {Optional, Raw, 0};
  194.     Hidden struct classinfo raw_input[] = {Araw_input};
  195.  
  196. Hidden classelem Aid_or_kw[] = {Tag, Keyword, 0};
  197.     Hidden struct classinfo id_or_kw[] = {Aid_or_kw};
  198. Hidden classelem Anumber[] = {Number, 0};
  199.     Hidden struct classinfo number[] = {Anumber};
  200. Hidden classelem Asign[] = {Optional, Plus_sign, Minus_sign, 0};
  201.     Hidden struct classinfo sign[] = {Asign};
  202.  
  203. Hidden classelem Ao_c_expr[] = {Optional, Collateral, EXPR, 0};
  204.     Hidden struct classinfo o_c_expr[] = {Ao_c_expr};
  205.  
  206. #define Ac_expr (Ao_c_expr+1)
  207.     Hidden struct classinfo c_expr[] = {Ac_expr};
  208. #define Aexpr (Ao_c_expr+2)
  209.     Hidden struct classinfo expr[] = {Aexpr};
  210. #define Aprimary (Ao_c_expr+5)
  211.     Hidden struct classinfo primary[] = {Aprimary};
  212.  
  213. Hidden classelem Ablock[] = {Operators, PRIMARY, 0};
  214.     Hidden struct classinfo block[] = {Ablock};
  215. Hidden classelem Agroup[] = {Blocked, Operators, PRIMARY, 0};
  216.     Hidden struct classinfo group[] = {Agroup};
  217.  
  218. #define Ar_expr Agroup
  219.     Hidden struct classinfo r_expr[] = {Ar_expr};
  220.  
  221. Hidden classelem Al_t_body[] =    {Optional, List_body, PRIMARY, Blocked, 
  222.     Grouped, Operators, Tab_body, Tab_entry, 0};
  223.     Hidden struct classinfo l_t_body[] = {Al_t_body};
  224. Hidden classelem Alist_body[] = {List_body, EXPR, 0};
  225.     Hidden struct classinfo list_body[] = {Alist_body};
  226. Hidden classelem Atab_body[] = {Tab_body, Tab_entry, 0};
  227.     Hidden struct classinfo tab_body[] = {Atab_body};
  228. Hidden classelem Atab_entry[] = {Tab_entry, 0};
  229.     Hidden struct classinfo tab_entry[] = {Atab_entry};
  230.  
  231. Hidden classelem Ac_target[] = {Col_target, TARGET, 0};
  232.     Hidden struct classinfo c_target[] = {Ac_target};
  233.  
  234. #define Atarget (Ac_target+1)
  235.     Hidden struct classinfo target[] = {Atarget};
  236.  
  237. #define SOME_ETC \
  238.     Not, Some_in, Each_in, No_in, Some_parsing, Each_parsing, No_parsing
  239.  
  240. Hidden classelem Ae_test[] = {Else_kw, SOME_ETC, And, Or, EXPR, 0};
  241.     Hidden struct classinfo e_test[] = {Ae_test};
  242.  
  243. #define Atest (Ae_test+1)
  244.     Hidden struct classinfo test[] = {Atest};
  245. #define At_test Aexpr
  246.     Hidden struct classinfo t_test[] = {At_test};
  247. Hidden classelem Ar_test[] = {SOME_ETC, EXPR, 0};
  248.     Hidden struct classinfo r_test[] = {Ar_test};
  249. Hidden classelem Aand_test[] = {SOME_ETC, And, EXPR, 0};
  250.     Hidden struct classinfo and_test[] = {Aand_test};
  251. Hidden classelem Aor_test[] = {SOME_ETC, Or, EXPR, 0};
  252.     Hidden struct classinfo or_test[] = {Aor_test};
  253. Hidden classelem Ac_test[] = {Collateral, SOME_ETC, And, Or, EXPR, 0};
  254.     Hidden struct classinfo c_test[] = {Ac_test};
  255.     /*
  256.      * This means that a compound expression may in fact
  257.      * contain a `collateral test', e.g. (a AND b, c AND d).
  258.      * Of course, this is illegal in B, but I couldn't
  259.      * solve the ambiguity of `(' where a test is expected
  260.      * otherwise (this may start a parenthesized test, or
  261.      * a compound expression; the latter may be followed
  262.      * by more expression fragments, the first may not).
  263.      */
  264.  
  265. Hidden classelem Acomment[] = {Comment, 0};
  266.     Hidden struct classinfo comment[] = {Acomment};
  267. Hidden classelem Ao_comment[] = {Optional, Comment, 0};
  268.     Hidden struct classinfo o_comment[] = {Ao_comment};
  269.     
  270. #define HEAD How_to, Yield, Test
  271. #define BODY HEAD, Cmt_head, Long_unit, Short_unit
  272.  
  273. /* The order here determines which are suggested first and is subject
  274.    to constant change! */
  275. #define SIMPLE_CMD SC1, SC2, SC3
  276. #define SC1 Share, Quit, Return, Write, Read, Read_raw, Put, Delete
  277. #define SC2 Report, Fail, Succeed, Insert, Remove, Check
  278. #define SC3 Choose, Draw, Set_random, Suggestion, Keyword, Kw_plus
  279.  
  280. #define CONTROL_CMD If, While, For
  281. #define COMP_CMD Short_comp, Long_comp, Cmt_comp, Select
  282. #define CMD If, For, COMP_CMD, SIMPLE_CMD, While
  283. /* #define SHORTCMD SIMPLE_CMD, Cmt_cmd */
  284. #define SHORTCMD If, For, SIMPLE_CMD, While, Short_comp, Cmt_comp, Cmt_cmd
  285.  
  286. Hidden classelem Ac_head[] = {Cmt_head, HEAD, 0};
  287.     Hidden struct classinfo c_head[] = {Ac_head};
  288. #define Ahead (Ac_head+1)
  289.     Hidden struct classinfo head[] = {Ahead};
  290.  
  291. Hidden classelem Aunit[] = {Optional, EXPR, BODY, Ref_join, 0};
  292.     Hidden struct classinfo unit[] = {Aunit};
  293. Hidden classelem Ao_refinements[] = {Optional, Refinement, 0};
  294.     Hidden struct classinfo o_refinements[] = {Ao_refinements};
  295. #define Arefinements (Ao_refinements+1)
  296.     Hidden struct classinfo refinements[] = {Arefinements};
  297. Hidden classelem Arefpred[] = {BODY, 0};
  298.     Hidden struct classinfo refpred[] = {Arefpred};
  299.  
  300. Hidden classelem Af_cmd[] = {Keyword, F_kw_plus, 0};
  301.     Hidden struct classinfo f_cmd[] = {Af_cmd};
  302. #define Af_formula Aexpr /*****/
  303.     Hidden struct classinfo f_formula[] = {Af_formula};
  304.  
  305. Hidden classelem Ao_suite[] = {Optional, Suite, 0};
  306.     Hidden struct classinfo o_suite[] = {Ao_suite};
  307. Hidden classelem At_suite[] = {Test_suite, 0};
  308.     Hidden struct classinfo t_suite[] = {At_suite};
  309. Hidden classelem Ao_t_suite[] = {Optional, Test_suite, 0};
  310.     Hidden struct classinfo o_t_suite[] = {Ao_t_suite};
  311.  
  312. Hidden classelem Acmd[] = {Comment, CMD, Cmt_cmd, 0};
  313.     Hidden struct classinfo cmd[] = {Acmd};
  314. Hidden classelem Ashortcmd[] = {SHORTCMD, 0};
  315.     Hidden struct classinfo shortcmd[] = {Ashortcmd};
  316. Hidden classelem Ao_cmdsuite[] = {Optional, SHORTCMD, Suite, 0};
  317.     Hidden struct classinfo o_cmdsuite[] = {Ao_cmdsuite};
  318. Hidden classelem Asuite[] = {Suite, 0};
  319.     Hidden struct classinfo suite[] = {Asuite};
  320. Hidden classelem Asimple_cmd[] = {SIMPLE_CMD, 0};
  321.     Hidden struct classinfo simple_cmd[] = {Asimple_cmd};
  322.  
  323. Hidden classelem Ac_ifforwhile[] = {CONTROL_CMD, Cmt_comp, 0};
  324.     Hidden struct classinfo c_ifforwhile[] = {Ac_ifforwhile};
  325. Hidden classelem Aifforwhile[] = {CONTROL_CMD, 0};
  326.     Hidden struct classinfo ifforwhile[] = {Aifforwhile};
  327.  
  328. Hidden classelem Akeyword[] = {Keyword, 0};
  329.     Hidden struct classinfo keyword[] = {Akeyword};
  330. Hidden classelem Akw_next[] = {Collateral, EXPR, Keyword, E_plus, Kw_plus, 0};
  331.     Hidden struct classinfo kw_next[] = {Akw_next};
  332. Hidden classelem Ae_next[] = {Keyword, Kw_plus, 0};
  333.     Hidden struct classinfo e_next[] = {Ae_next};
  334.  
  335. Hidden classelem Af_kw_next[] = {Tag, Keyword, F_kw_plus, F_e_plus, 0};
  336.     Hidden struct classinfo f_kw_next[] = {Af_kw_next};
  337. Hidden classelem Af_e_next[] = {Keyword, F_kw_plus, 0};
  338.     Hidden struct classinfo f_e_next[] = {Af_e_next};
  339. Hidden classelem Atag[] = {Tag, 0};
  340.     Hidden struct classinfo tag[] = {Atag};
  341.  
  342. Hidden classelem Atext1[] = {Optional, T1, Conversion, T1_plus, 0};
  343.     Hidden struct classinfo text1[] = {Atext1};
  344. Hidden classelem At1_conv[] = {T1, Conversion, 0};
  345.     Hidden struct classinfo t1_conv[] = {At1_conv};
  346. Hidden classelem At1_next[] = {T1, Conversion, T1_plus, 0};
  347.     Hidden struct classinfo t1_next[] = {At1_next};
  348.  
  349. Hidden classelem Atext2[] = {Optional, T2, Conversion, T2_plus, 0};
  350.     Hidden struct classinfo text2[] = {Atext2};
  351. Hidden classelem At2_conv[] = {T2, Conversion, 0};
  352.     Hidden struct classinfo t2_conv[] = {At2_conv};
  353. Hidden classelem At2_next[] = {T2, Conversion, T2_plus, 0};
  354.     Hidden struct classinfo t2_next[] = {At2_next};
  355.  
  356. Hidden classelem Aand[] = {And_kw, 0};
  357.     Hidden struct classinfo and[] = {Aand};
  358. Hidden classelem Aor[] = {Or_kw, 0};
  359.     Hidden struct classinfo or[] = {Aor};
  360.  
  361. Hidden classelem Ae_part[] = {E_part, 0};
  362.     Hidden struct classinfo e_part[] = {Ae_part};
  363.  
  364. Hidden classelem Aunit_edit[] = {Optional, BODY, Ref_join, 0};
  365.     Hidden struct classinfo unit_edit[] = {Aunit_edit};
  366. Hidden classelem Atarget_edit[] = {Optional, EXPR, 0};
  367.     Hidden struct classinfo target_edit[] = {Atarget_edit};
  368. Hidden classelem Aimm_cmd[] = {Optional, Comment, HEAD, CMD, Cmt_cmd, Cmt_head,
  369.     Edit_unit, Edit_target, 0};
  370.     Hidden struct classinfo imm_cmd[] = {Aimm_cmd};
  371.  
  372. Hidden classelem Aed_unit[] = {Optional, Tag, Keyword, Colon, 0};
  373.     Hidden struct classinfo ed_unit[] = {Aed_unit};
  374. Hidden classelem Aed_target[] = {Optional, Tag, Equals, 0};
  375.     Hidden struct classinfo ed_target[] = {Aed_target};
  376.  
  377.  
  378. /*
  379.  * WARNING: The entries in this table must correspond one by one
  380.  * to the symbols defined earlier.  This is checked dynamically
  381.  * by the initialization procedure (syserr "table order").
  382.  */
  383.  
  384. #define XX(name) name, "name"
  385.  
  386. Hidden struct table b_grammar[] = {
  387.     {XX(Rootsymbol), {0}, {unit}}, /* Start symbol of the grammar,
  388.             may be overridden by setroot("Blabla") call. */
  389.     {XX(Put), {"PUT ", " IN "}, {c_expr, c_target}},
  390.     {XX(Insert), {"INSERT ", " IN "}, {c_expr, target}},
  391.     {XX(Remove), {"REMOVE ", " FROM "}, {c_expr, target}},
  392.     {XX(Choose), {"CHOOSE ", " FROM "}, {c_expr, expr}},
  393.     {XX(Draw), {"DRAW "}, {target}},
  394.     {XX(Set_random), {"SET'RANDOM "}, {c_expr}},
  395.     {XX(Delete), {"DELETE "}, {c_target}},
  396.     {XX(Check), {"CHECK "}, {test}},
  397.     {XX(Share), {"SHARE "}, {c_target}},
  398.  
  399.     {XX(Write), {"WRITE "}, {c_expr}},
  400.     {XX(Read), {"READ ", " EG "}, {c_target, c_expr}},
  401.     {XX(Read_raw), {"READ ", " RAW"}, {target}},
  402.  
  403.     {XX(If), {"IF ", ": "}, {test}},
  404.     {XX(While), {"WHILE ", ": "}, {test}},
  405.     {XX(For), {"FOR ", " IN ", ": "}, {c_target, expr}},
  406.  
  407.     {XX(Select), {"SELECT: ", "\t", "\b"}, {o_comment, t_suite}},
  408.     {0}, /* Test_suite moved to 92 */
  409.  
  410.     {XX(Quit), {"QUIT"}, {0}},
  411.     {XX(Return), {"RETURN "}, {c_expr}},
  412.     {XX(Report), {"REPORT "}, {test}},
  413.     {XX(Succeed), {"SUCCEED"}, {0}},
  414.     {XX(Fail), {"FAIL"}, {0}},
  415.  
  416.     {XX(How_to), {"HOW'TO ", ": "}, {f_cmd}},
  417.     {XX(Yield), {"YIELD ", ": "}, {f_formula}},
  418.     {XX(Test), {"TEST ", ": "}, {f_formula}},
  419.  
  420.     {XX(Suite), {"\n"}, {cmd, o_suite}},
  421.     {XX(Refinement), {"\n", ": ", "\t", "\b"},
  422.         {id_or_kw, o_comment, o_cmdsuite, o_refinements}},
  423.  
  424.     {XX(Compound), {"(", ")"}, {c_test}},
  425.     {XX(Collateral), {0, ", "}, {expr, c_expr}},
  426.     {XX(Tag), {0}, {tag_body}},
  427.     {XX(Number), {0}, {num_body}},
  428.     {XX(Selection), {0, "[", "]"}, {target, c_expr}},
  429.     {XX(Behead), {0, "@"}, {target, r_expr}},
  430.     {XX(Curtail), {0, "|"}, {target, r_expr}},
  431.  
  432.     {XX(And), {0, " "}, {t_test, and}},
  433.     {XX(Or), {0, " "}, {t_test, or}},
  434.     {XX(Not), {"NOT "}, {r_test}},
  435.     {XX(Some_in), {"SOME ", " IN ", " HAS "}, {c_target, expr, r_test}},
  436.     {XX(Each_in), {"EACH ", " IN ", " HAS "}, {c_target, expr, r_test}},
  437.     {XX(No_in), {"NO ", " IN ", " HAS "}, {c_target, expr, r_test}},
  438.     {XX(Some_parsing), {"SOME ", " PARSING ", " HAS "},
  439.         {c_target, expr, r_test}},
  440.     {XX(Each_parsing), {"EACH ", " PARSING ", " HAS "},
  441.         {c_target, expr, r_test}},
  442.     {XX(No_parsing), {"NO ", " PARSING ", " HAS "}, {c_target, expr, r_test}},
  443.  
  444.     {XX(Comment), {0}, {com_body}},
  445.     {XX(Keyword), {0}, {kw_body}},
  446.  
  447.     {XX(L_t_dis), {"{", "}"}, {l_t_body}},
  448.     {XX(List_body), {0, "; "}, {expr, list_body}},
  449.     {XX(Tab_body), {0, "; "}, {tab_entry, tab_body}},
  450.     {XX(Tab_entry), {"[", "]: "}, {c_expr, expr}},
  451.     {XX(E_number), {0}, {number, e_part}},
  452.  
  453.     {XX(Com_target), {"(", ")"}, {c_target}},
  454.     {XX(Col_target), {0, ", "}, {target, c_target}},
  455.     {XX(Sel_expr), {0, "[", "]"}, {primary, c_expr}},
  456.  
  457.     {XX(Text1), {"'", "'"}, {text1}},
  458.     {XX(Text2), {"\"", "\""}, {text2}},
  459.     {XX(Grouped), {0, " "}, {group, expr}},
  460.     {XX(Blocked), {0}, {block, group}},
  461.     {XX(Operators), {0}, {ops_body}},
  462.     {XX(Else_kw), {"ELSE"}, {0}},
  463.     {XX(Kw_plus), {0, " "}, {keyword, kw_next}},
  464.     {XX(E_plus), {0, " "}, {c_expr, e_next}},
  465.     {XX(Conversion), {"`", "`"}, {o_c_expr}},
  466.     {XX(T1), {0}, {t1_body}},
  467.     {XX(T1_plus), {0}, {t1_conv, t1_next}},
  468.     {XX(T2), {0}, {t2_body}},
  469.     {XX(T2_plus), {0}, {t2_conv, t2_next}},
  470.     {XX(Cmt_cmd), {0, " "}, {simple_cmd, comment}},
  471.     {0},
  472.     {XX(F_kw_plus), {0, " "}, {keyword, f_kw_next}},
  473.     {XX(F_e_plus), {0, " "}, {tag, f_e_next}},
  474.     {XX(Plus_sign), {"+"}, {0}},
  475.     {XX(Minus_sign), {"-"}, {0}},
  476.  
  477.     {XX(Long_comp), {0, "\t", "\b"}, {c_ifforwhile, suite}},
  478.     {XX(Short_comp), {0, "\t", "\b"}, {ifforwhile, shortcmd}},
  479.     {XX(Cmt_comp), {0}, {ifforwhile, comment}},
  480.  
  481.     {XX(Long_unit), {0, "\t", "\b"}, {c_head, suite}},
  482.     {XX(Short_unit), {0, "\t", "\b"}, {head, shortcmd}},
  483.     {XX(Cmt_head), {0}, {head, comment}},
  484.  
  485.     {XX(Ref_join), {0}, {refpred, refinements}},
  486.  
  487.     {XX(And_kw), {"AND "}, {and_test}},
  488.     {XX(Or_kw), {"OR "}, {or_test}},
  489.  
  490.     {XX(E_part), {"E"}, {sign, number}},
  491.  
  492.     /* Alternate root symbols */
  493.  
  494.     {XX(Unit_edit), {0}, {unit_edit}},
  495.     {XX(Target_edit), {0}, {target_edit}},
  496.     {XX(Imm_cmd), {0}, {imm_cmd}},
  497.     {XX(Raw), {0}, {raw_body}},
  498.     {XX(Raw_input), {0}, {raw_input}},
  499.     {XX(Edit_unit), {":"}, {ed_unit}},
  500.     {XX(Edit_target), {"="}, {ed_target}},
  501.     {XX(Colon), {":"}, {0}},
  502.     {XX(Equals), {"="}, {0}},
  503.     {XX(Test_suite), {"\n", ": ", "\t", "\b"},
  504.         {e_test, o_comment, o_cmdsuite, o_t_suite}},
  505.     {XX(Expression), {0}, {c_expr}},
  506.  
  507.     /* Spare(s); change Optional and Hole in "gram.h" if you run out. */
  508.  
  509.     {0}, {0}, {0},
  510.  
  511.     /* Next three entries must be the last entries of the table. */
  512.     /* (See comments in "gram.c", initgram().) */
  513.  
  514.     {XX(Suggestion), {0}, {sugg_body}},
  515.     {XX(Optional), {0}, {0}},
  516.     {XX(Hole), {"?"}, {0}},
  517. };
  518.  
  519. Visible struct table *table= b_grammar;
  520.